/*
 * Licensed to the Tai Ping Jin Ke
 *
 * Copyright (c) 2022 .
 * All rights reserved.
 * 项目名称：太平金科-基础组件封装层-对象存储服务OSS-核心依赖
 * 版权说明：本软件属太平金融科技服务(上海)有限公司所有，在未获得太平金融科技服务(上海)有限公司正式授权情况下，任何企业和个人，不能获取、阅读、安装、传播本软件涉及的任何受知识产权保护的内容。
 */
package com.taipingframework.boot.minio.bucket;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.taipingframework.boot.minio.bucket.policy.BucketPolicyArgs;
import com.taipingframework.boot.minio.bucket.policy.PolicyStatement;
import org.apache.commons.lang3.StringUtils;

/**
 * Bucket Information
 * <p>
 * <p>
 * ① Version：版本的意思，好像是固定的，看了大家都这么写，没找到原因
 * <p>
 * ② Actions：对于每个资源，Amazon S3 支持一组操作。您可以使用操作关键字标识将允许（或拒绝）的资源操作。
 * Actions支持以下操作：
 * ● s3:GetObject
 * ● s3:ListBucket
 * ● s3:PutObject
 * ● s3:GetBucketLocation
 * ● s3:DeleteObject
 * ● s3:AbortMultipartUpload
 * ● s3:ListBucketMultipartUploads
 * ● s3:ListMultipartUploadParts
 * <p>
 * ③ Principal：被允许访问语句中的操作和资源的帐户或用户。在存储桶策略中，委托人是作为此权限接收者的用户、账户、服务或其他实体。
 * <p>
 * ④ Condition：政策生效的条件。您可以使用 AWS 范围的密钥和 Amazon S3 特定的密钥来指定 Amazon S3 访问策略中的条件。
 * <p>
 * ⑤ Resource：存储桶、对象、访问点和作业是您可以允许或拒绝权限的 Amazon S3 资源。在策略中，您使用 Amazon 资源名称 (ARN) 来标识资源。
 * <p>
 * ⑥ Effect：对于每个资源，Amazon S3 支持一组操作。您可以使用操作关键字标识将允许（或拒绝）的资源操作。如：该s3:ListBucket权限允许用户使用 Amazon S3 GET Bucket (List Objects)操作。
 */
public interface BucketConstant {

    /**
     * 返回存储桶的名称
     */
    String bucketName();

    /**
     * 区域，例如"us-west-1"。
     * 对于单节点MinIO实例，通常可以设置为"us-east-1"或留空。
     */
    String region();

    /**
     * 是否启用MinIO对象锁定功能
     * <p>
     * MinIO对象锁定（“对象保留”）实施一次写入多次读取（Write-Once Read-Many，WORM）的不可变性，
     * 以保护 版本对象 不可以 被删除。
     * MinIO支持两种对象保留方式： 基于持续时间的对象保留 和 无限期合法保留。
     */
    default Boolean objectLock() {
        return false;
    }

    /**
     * 存储桶的策略
     */
    BucketPolicyArgs bucketPolicyArgs();

    /**
     * 构建“读写”Bucket权限参数
     */
    static BucketPolicyArgs buildReadAndWritePolicyArgs(String bucketName) {
        BucketPolicyArgs bucketPolicyArgs = new BucketPolicyArgs();
        bucketPolicyArgs.setVersion("2012-10-17");
        bucketPolicyArgs.setStatement(ImmutableList.of(
                PolicyStatement.builder()
                        .effect("Allow")
                        .principal(ImmutableMap.of("AWS", ImmutableList.of("*")))
                        .action(ImmutableList.of("s3:GetBucketLocation", "s3:ListBucket", "s3:ListBucketMultipartUploads"))
                        .resource(ImmutableList.of(String.join(StringUtils.EMPTY, "arn:aws:s3:::", bucketName)))
                        .build(),
                PolicyStatement.builder()
                        .effect("Allow")
                        .principal(ImmutableMap.of("AWS", ImmutableList.of("*")))
                        .action(ImmutableList.of("s3:DeleteObject", "s3:GetObject", "s3:ListMultipartUploadParts", "s3:PutObject", "s3:AbortMultipartUpload"))
                        .resource(ImmutableList.of(String.join(StringUtils.EMPTY, "arn:aws:s3:::", bucketName, "/*")))
                        .build()
        ));
        return bucketPolicyArgs;
    }

    /**
     * 构建“只读”Bucket权限参数
     */
    static BucketPolicyArgs buildReadOnlyPolicyArgs(String bucketName) {
        BucketPolicyArgs bucketPolicyArgs = new BucketPolicyArgs();
        bucketPolicyArgs.setVersion("2012-10-17");
        bucketPolicyArgs.setStatement(ImmutableList.of(
                PolicyStatement.builder()
                        .effect("Allow")
                        .principal(ImmutableMap.of("AWS", ImmutableList.of("*")))
                        .action(ImmutableList.of("s3:GetBucketLocation", "s3:ListBucketMultipartUploads"))
                        .resource(ImmutableList.of(String.join(StringUtils.EMPTY, "arn:aws:s3:::", bucketName)))
                        .build(),
                PolicyStatement.builder()
                        .effect("Allow")
                        .principal(ImmutableMap.of("AWS", ImmutableList.of("*")))
                        .action(ImmutableList.of("s3:GetObject", "s3:ListMultipartUploadParts", "s3:AbortMultipartUpload"))
                        .resource(ImmutableList.of(String.join(StringUtils.EMPTY, "arn:aws:s3:::", bucketName, "/*")))
                        .build()
        ));
        return bucketPolicyArgs;
    }

}
